package x.trident.core.micro.tran.message.modular.service.impl;

import cn.hutool.core.bean.BeanUtil;
import x.trident.core.micro.tran.message.modular.service.AbstractMessageChecker;
import x.trident.core.db.api.pojo.page.PageResult;
import x.trident.core.micro.api.TranMessageServiceApi;
import x.trident.core.micro.api.pojo.TranMessage;
import x.trident.core.micro.api.pojo.request.TranMessageRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Map;

/**
 * 处理状态为“发送中”但超时没有被成功消费确认的消息
 *
 * @author Seven
 * @date 2018-05-08 23:07
 */
@Service
@Slf4j
public class SendingMessageChecker extends AbstractMessageChecker {

    @Resource
    private TranMessageServiceApi tranMessageServiceApi;

    @Resource(name = "sendTimeInterval")
    private Map<Integer, Integer> notifyParam;

    @Override
    protected void processMessage(Map<String, TranMessage> messageMap) {

        // 单条消息处理
        for (Map.Entry<String, TranMessage> entry : messageMap.entrySet()) {
            TranMessage message = entry.getValue();
            try {
                // 判断发送次数
                int maxTimes = notifyParam.size();

                // 如果超过最大发送次数直接退出
                if (message.getMessageSendTimes() > maxTimes) {

                    // 标记为死亡
                    tranMessageServiceApi.setMessageToAlreadlyDead(message.getMessageId());
                    continue;
                }

                // 获取消息已经从发的次数
                int reSendTimes = message.getMessageSendTimes();

                // 获取再次发送的间隔分钟数，每次从发间隔不一样
                int reSendIntervalMinutes = notifyParam.get(reSendTimes == 0 ? 1 : reSendTimes);

                // 获取当前时间
                long currentTimeInMillis = Calendar.getInstance().getTimeInMillis();

                // 获取推算的下次发送的时间
                long nextExecuteTime = message.getUpdateTime().getTime() + reSendIntervalMinutes * 60 * 1000L;

                // 若当前时间超过推算的发送时间，则重新发送消息
                if (currentTimeInMillis >= nextExecuteTime) {
                    TranMessageRequest tranMessageRequest = new TranMessageRequest();
                    BeanUtil.copyProperties(message, tranMessageRequest);
                    tranMessageServiceApi.reSendMessage(tranMessageRequest);
                }

            } catch (Exception e) {
                log.error("处理[SENDING]消息ID为[" + message.getMessageId() + "]的消息异常：", e);
            }
        }

    }

    @Override
    protected PageResult<TranMessage> getPageResult(TranMessageRequest tranMessageRequest) {
        return tranMessageServiceApi.listPageSendingTimeOutMessages(tranMessageRequest);
    }

}
